<?php

namespace app\modules\film\service;

use Yii;
use yii\helpers\ArrayHelper;
use app\common\behaviors\ApiCommonBehavior;
use app\common\base\ApiService;
use app\modules\film\models\Film;
use app\modules\film\models\FilmType;
use app\modules\film\models\TypeOfFilm;
use DateTime;
use Exception;
use app\helpers\DatetimeHelper;
use DateTimeInterface;
use yii\helpers\HtmlPurifier;

class FilmService extends ApiService
{
    function __construct()
    {
        parent::init();
        $this->model = new Film();
    }

    public function getAll(){
        return $this->getByCondition(['status' => 1]);
    }

    public function getByCondition($condition, $orderBy = 'id asc', $page = null, $size = null){
        $init = [
            'status' => 1,
        ];
        $condition = array_merge($condition, $init);
        //设置了影片类型的话先根据影片类型查询出影片的id
        if(isset($condition['film_type'])){       
            $typeIds = ArrayHelper::getColumn(ApiCommonBehavior::call('film', 'FilmTypeService', 'lists', [
                'condition' => [
                    'type_name' => $condition['film_type'],
                ],
            ]), 'film_type');   //获得对应的影片类型的id
                   
            $filmIds = ArrayHelper::getColumn(ApiCommonBehavior::call('film', 'TypeOfFilmService', 'lists', [
                'condition' => [
                    'type_id' => $typeIds,
                ],
            ]), 'film_id');     //获取对应的影片id
            unset($condition['film_type']);
            if(isset($condition['id'])){    //如果已经限定了影片的id就对两个id取交集
                $condition['id'] = array_intersect($condition['id'],$filmIds);
            }else{
                $condition = array_merge($condition, ['id' => $filmIds]);
            }
        }
        $count = $this->countInCondition($condition);
        $infos = $this->lists([
            'condition' => $condition,
            'with' => 'filmType',
            'orderby' => $orderBy,
            'page' => $page,
            'size' => $size,
        ]);

        //整理
        foreach($infos as &$info){
            $type_name = [];
            foreach($info['filmType'] as $one){
                $type_name[] = $one['filmType'][0]['type_name'];      
            }
            $info['film_type'] = $type_name;
            unset($info['filmType']);
        }

        return [
            'count' => $count,
            'info' => $infos,
        ];
    }


    /**
     * 关键词搜索;
     */
    public function search($something, $somethingLlike){
        $something = HtmlPurifier::process($something); //过滤敏感代码
        $somethingLlike = HtmlPurifier::process($somethingLlike); //过滤敏感代码
        
        $infos = [];
        //设置影片类型的话根据影片类型查询出影片的id
        if('film_type' == $something){       
            $typeIds = ArrayHelper::getColumn(ApiCommonBehavior::call('film', 'FilmTypeService', 'lists', [
                'condition' => [
                    'and',
                    ['like', 'type_name', $somethingLlike],
                ],
            ]), 'film_type');   //获得对应的影片类型的id
            $filmIds = ArrayHelper::getColumn(ApiCommonBehavior::call('film', 'TypeOfFilmService', 'lists', [
                'condition' => [
                    'type_id' => $typeIds,
                ],
            ]), 'film_id');     //获取对应的影片id
            $init = [
                'and',
                ['=', 'status', 1],
                ['in', 'id', $filmIds]
            ];
        }else{
            $init = [
                'and',
                ['=', 'status', 1],
                ['like', $something, $somethingLlike]
            ];
            
        }

        $infos = $this->lists([
            'condition' => $init,
            'with' => 'filmType',
            'orderby' => 'id asc'
        ]);
        
        
        //整理
        foreach($infos as &$info){
            $type_name = [];
            foreach($info['filmType'] as $one){
                $type_name[] = $one['filmType'][0]['type_name'];      
            }
            $info['film_type'] = $type_name;
            unset($info['filmType']);
        }

        return $infos;
    }

    /**
     * 购票;
     * 需要传入ticket的id;
     * $userId是用户id;
     */
    public function TicketBuyById($ticketId, $amount, $userId){
        $userInfo = ApiCommonBehavior::call('user', 'AccountService', 'info', [
            'condition' => [
                'id' => $userId,
            ]
        ]);
        if(empty($userInfo)){            //找不到用户
            return ApiCommonBehavior::error('ERROR_INVALID_USERID', '用户不存在');
        }

        $connection =  Yii::$app->db;
        $transaction = $connection->beginTransaction();
        try{
            $info = ApiCommonBehavior::call('film', 'FilmTicketService', 'info', [
                'condition' => [
                    'and',
                    ['=', 'status', 1],
                    ['=', 'id', $ticketId],
                ]
            ]);
            if(empty($info)){
                throw new Exception("ERROR_NO_TICKET_INFO", 102);
            }

            $seat_num = $info['amount_sum'] - $info['amount_left'] + 1;
            $sql = 'UPDATE film_ticket SET amount_left = amount_left - '.$amount
                .' WHERE id = '.$ticketId.' AND status = 1';
            $res = $connection->createCommand($sql)->execute();
            if(0 == $res){
                throw new Exception("ERROR_NO_ENOUGH_TICKET", 100);
            }

            $timeNow = DatetimeHelper::msectime();
            $dateTime = date('Y-m-d H:m:s', $timeNow / 1000);
            
            $sql = 'INSERT INTO record_ticket_buy(user_id, amount, create_timestamp, date_time, seat_num, ticket_id) 
            VALUES("'.$userId.'", "'.$amount.'", "'.$timeNow.'", "'.$dateTime.'", "'.$seat_num.'", '.$info['id'].')';
            $res = $connection->createCommand($sql)->execute();
            if(0 == $res){
                throw new Exception("ERROR_GENERATE_RECORD_FAILED", 101);
            }
            $transaction->commit();
        }catch(Exception $e){
            $transaction->rollBack();
            $code = $e->getCode();
            switch($code){
                case 100:
                    return ApiCommonBehavior::error('ERROR_NO_ENOUGH_TICKET', '剩余票数不足');
                case 101:
                    return ApiCommonBehavior::error('ERROR_GENERATE_RECORD_FAILED', '购票记录生成失败');
                case 102:
                    return ApiCommonBehavior::error('ERROR_NO_TICKET_INFO', '没有检索到该售票信息');
                default:
                    throw $e;   //其他问题
            }
        }
        //返回购票记录
        $res = ApiCommonBehavior::call('film', 'RecordTicketBuyService', 'info', [
            'condition' => [
                'and',
                ['=', 'status', 1],
                ['=', 'user_id', $userId],
                ['=', 'amount', $amount],
                ['=', 'create_timestamp', $timeNow],
                ['=', 'date_time', $dateTime],
                ['=', 'seat_num', $seat_num],
                ['=', 'ticket_id', $info['id']],
            ]
        ]);
        return $res;
    }

    /**
     * 购票;
     * $msg是一个数组，需要包括film_id、amount、show_times、video_hall，分别代表影片id与订票数目;
     * $userId是用户id;
     */
    public function TicketBuy($msg, $userId){
        if(!isset($msg['film_id']) or !isset($msg['amount']) 
            or !isset($msg['show_times']) or !isset($msg['video_hall'])){  //没有设置必要信息
            return false;
        }
        $userInfo = ApiCommonBehavior::call('user', 'AccountService', 'info', [
            'condition' => [
                'id' => $userId,
            ]
        ]);

        if(empty($userInfo)){            //找不到用户
            return ApiCommonBehavior::error('ERROR_INVALID_USERID', '用户不存在');
        }

        $connection =  Yii::$app->db;
        $transaction = $connection->beginTransaction();
        try{
            $info = ApiCommonBehavior::call('film', 'FilmTicketService', 'info', [
                'condition' => [
                    'and',
                    ['=', 'status', 1],
                    ['=', 'film_id', $msg['film_id']],
                    ['=', 'show_times', $msg['show_times']],
                    ['=', 'video_hall', $msg['video_hall']],
                ]
            ]);
            if(empty($info)){
                throw new Exception("ERROR_NO_TICKET_INFO", 102);
            }

            $seat_num = $info['amount_sum'] - $info['amount_left'] + 1;
            $sql = 'UPDATE film_ticket SET amount_left = amount_left - '.$msg['amount']
                .' WHERE film_id = '.$msg['film_id'].' AND show_times = '.$msg['show_times']
                .' AND amount_left >= '.$msg['amount'].' AND video_hall = '.$msg['video_hall'].' AND status=1';
            $res = $connection->createCommand($sql)->execute();
            if(0 == $res){
                throw new Exception("ERROR_NO_ENOUGH_TICKET", 100);
            }

            $timeNow = DatetimeHelper::msectime();
            $dateTime = date('Y-m-d H:m:s', $timeNow / 1000);
            
            $sql = 'INSERT INTO record_ticket_buy(user_id, amount, create_timestamp, date_time, seat_num, ticket_id) 
            VALUES("'.$userId.'", "'.$msg['amount'].'", "'.$timeNow.'", "'.$dateTime.'", "'.$seat_num.'", '.$info['id'].')';
            $res = $connection->createCommand($sql)->execute();
            if(0 == $res){
                throw new Exception("ERROR_GENERATE_RECORD_FAILED", 101);
            }
            $transaction->commit();
        }catch(Exception $e){
            $transaction->rollBack();
            $code = $e->getCode();
            switch($code){
                case 100:
                    return ApiCommonBehavior::error('ERROR_NO_ENOUGH_TICKET', '剩余票数不足');
                case 101:
                    return ApiCommonBehavior::error('ERROR_GENERATE_RECORD_FAILED', '购票记录生成失败');
                case 102:
                    return ApiCommonBehavior::error('ERROR_NO_TICKET_INFO', '没有检索到该售票信息');
                default:
                    throw $e;   //其他问题
            }
        }
        //返回购票记录
        $res = ApiCommonBehavior::call('film', 'RecordTicketBuyService', 'info', [
            'condition' => [
                'and',
                ['=', 'status', 1],
                ['=', 'user_id', $userId],
                ['=', 'amount', $msg['amount']],
                ['=', 'create_timestamp', $timeNow],
                ['=', 'date_time', $dateTime],
                ['=', 'seat_num', $seat_num],
                ['=', 'ticket_id', $info['id']],
            ]
        ]);
        return $res;
    }

    /**
     * 返回今日推荐;
     */
    public function getRecommendListToday(){
        $timeNow = DatetimeHelper::msectime();
        $timeYes = $timeNow - 24*60*60*1000;
        $infos = ApiCommonBehavior::call(
            'film',
            'RecordTicketBuyService',
            'lists',
            [
                'condition' => [
                    'and',
                    ['>', 'create_timestamp', $timeYes],
                    ['=', 'status', 1]
                ]
            ]
        );
        $recommend = [];
        $filmIds = [];
        foreach($infos as $info){
            $recommend[$info['film_id']] = $recommend[$info['film_id']] ?? 0;
            $recommend[$info['film_id']] += $info['amount'];
            $filmIds[] = $info['film_id'];
        }

        $list = ApiCommonBehavior::call('film', 'FilmService', 'lists', [
            'condition' => [
                'id' => $filmIds,
            ]
        ]);
        $res = [];
        foreach($list as $one){
            $res[$one['film_name']] = $recommend[$one['id']];
        }
        arsort($res);
        return $res;

    }


}

